<template>
  <mu-flex id="health-index-root" direction="column">
    <mu-appbar id="appBar" :z-depth="2" color="primary" title="健康指数">
      <mu-button icon slot="right" @click="onAddClick">
        <mu-icon value="add"></mu-icon>
      </mu-button>
    </mu-appbar>

    <mu-flex id="content" direction="column">
      <mu-flex id="weight-wrap" align-items="baseline" justify-content="center">
        <span id="weight">{{ weight }}</span><span id="weight-unit">公斤</span>
      </mu-flex>

      <mu-flex id="other-wrap" justify-content="center">
        <mu-button
                id="height-wrap"
                class="d-flex flex-fill justify-content-start align-items-center"
                flat
                @click="onHeightClick">
          <mu-flex direction="column" align-items="center" fill>
            <span id="height-label">身高</span>
            <mu-flex align-items="baseline">
              <span id="height">{{ height }}</span><span id="height-unit">米</span>
            </mu-flex>
          </mu-flex>
        </mu-button>
        <mu-flex id="bmi-wrap" direction="column" align-items="center" fill>
          <span id="bmi-label">BMI</span>
          <mu-flex align-items="baseline">
            <span id="bmi">{{ bmi }}</span><span id="bmi-text">{{ bmiText }}</span>
          </mu-flex>
        </mu-flex>
        <mu-flex id="compare-wrap" direction="column" align-items="center" fill>
          <span id="compare-label">比上次</span>
          <mu-flex align-items="baseline">
            <span id="compare">{{ comparedValue }}</span><span id="compare-unit">公斤</span>
          </mu-flex>
        </mu-flex>
      </mu-flex>

      <la-cartesian
              id="chart"
              :width="chartWidth"
              :height="chartWidth * 0.8"
              :bound="bound"
              :data="chartData"
              v-if="isShowChart">
        <la-area dot color="#B2DFDB" fill-color="#E0F2F1" prop="weight"></la-area>
        <la-x-axis prop="x"></la-x-axis>
        <la-y-axis></la-y-axis>
        <la-tooltip></la-tooltip>
      </la-cartesian>
    </mu-flex>

    <mu-dialog :title="dialogTitle" width="80%" :open.sync="isOpenDialog">

      <mu-form ref="form" :model="form" v-if="isAddingWeight">
        <mu-form-item
                class="form-item"
                label="体重（公斤）"
                prop="weight"
                :rules="weightRules">
          <mu-text-field v-model="form.weight" prop="weight"></mu-text-field>
        </mu-form-item>
      </mu-form>

      <mu-form ref="form" :model="form" v-if="!isAddingWeight">
        <mu-form-item
                class="form-item"
                label="身高（米）"
                prop="height"
                :rules="heightRules">
          <mu-text-field v-model="form.height" prop="height"></mu-text-field>
        </mu-form-item>
      </mu-form>

      <mu-button slot="actions" flat color="primary" @click="onDialogCancel">取消</mu-button>
      <mu-button slot="actions" flat color="primary" @click="onDialogConfirm">确定</mu-button>
    </mu-dialog>
  </mu-flex>
</template>

<script lang="ts">
  import BmiService from '../../service/bmi/BmiService';
  import {SUCCESS} from '../../common/ErrorCode';

  let constant = {
    network_error: '网络异常',
    add_weight: '添加体重',
    modify_height: '修改身高',
  };

  export default {
    data() {
      return {
        // 先隐藏图标，不然浏览器会输出一大堆错误
        isShowChart: false,
        weight: 0,
        height: 0,
        chartWidth: 0,
        chartData: [],
        dialogTitle: constant.add_weight,
        isOpenDialog: false,
        isAddingWeight: false,
        form: {
          height: undefined,
          weight: undefined
        },
        heightRules: [
          { validate: (val) => !isNaN(Number(val)), message: '无效的身高'},
        ],
        weightRules: [
          { validate: (val) => !isNaN(Number(val)), message: '无效的体重'},
        ],
      }
    },
    mounted() {
      this.chartWidth = document.getElementById("health-index-root").clientWidth;
      this.loadData();
    },
    computed: {
      bmi() {
        return (this.weight / (this.height * this.height)).toFixed(1);
      },
      bmiText() {
        let bmi = this.bmi;
        if (bmi < 18.5) {
          return '偏瘦';
        } else if (bmi <= 23.9) {
          return '正常';
        } else if (bmi <= 27) {
          return '偏胖';
        } else if (bmi <= 32) {
          return '肥胖';
        } else {
          return '极胖';
        }
      },
      comparedValue() {
        if (!this.chartData || this.chartData.length <= 1) {
          return '+' + this.weight;
        }

        let result = this.weight - this.chartData[this.chartData.length - 2].weight;
        if (result > 0) {
          return '+' + result.toFixed(1);
        }
        return result.toFixed(1);
      },
      bound() {
        if (this.chartData.length === 0) {
          return [0];
        }

        let min = this.chartData[0].weight;
        let max = min;
        this.chartData.forEach(value => {
          if (value.weight < min) {
            min = value.weight;
          }
          if (value.weight > max) {
            max = value.weight;
          }
        });
        return [Math.floor(min), Math.ceil(max)];
      }
    },
    methods: {
      loadData() {
        BmiService.getBmiData()
            .then(res => {
              if (res.code === SUCCESS) {
                // 返回数据的身高是厘米
                this.height = (res.value.height / 100).toFixed(2);
                let weights = res.value.weights;
                let data = [];
                if (weights.length > 7) {
                  weights = weights.slice(0, 7);
                } else if (weights.length < 2) {
                  let date = new Date();
                  let time = [
                      date.getFullYear(),
                      date.getMonth() + 1,
                      date.getDate(),
                      date.getHours(),
                      date.getMinutes(),
                      date.getSeconds()
                  ];
                  for (let i = 0, len = 2 - weights.length; i < len; i++) {
                    weights.push({weight: 1 - i, time: time});
                  }
                }
                weights.forEach(value => {
                  // 坐标的x轴显示文字
                  value['x'] = `${value.time[1]}.${value.time[2]}`;
                  data.push(value);
                });

                // 日期正序排序
                this.chartData = data.reverse();
                this.weight = this.chartData[this.chartData.length - 1].weight;

                // 显示图表
                this.isShowChart = true;
              } else {
                this.$toast.info(res.message);
              }
            })
            .catch(e => {
              console.log(e);
              this.$toast.info(constant.network_error);
            });
      },
      onAddClick() {
        this.isOpenDialog = true;
        this.isAddingWeight = true;
        this.dialogTitle = constant.add_weight;
      },
      onHeightClick() {
        this.isOpenDialog = true;
        this.isAddingWeight = false;
        this.dialogTitle = constant.modify_height;
      },
      onDialogCancel() {
        this.isOpenDialog = false;
      },
      onDialogConfirm() {

        this.$refs.form.validate().then((result) => {
          if (result) {
            if (this.isAddingWeight) {
              // 添加体重
              BmiService.addWeight(Number(this.form.weight))
                  .then(res => {
                    if (res.code === SUCCESS) {
                      this.isOpenDialog = false;
                      this.$toast.info('添加成功');
                      this.loadData();
                    } else {
                      this.$toast.info(res.message);
                    }
                  })
                  .catch(e => {
                    console.log(e);
                    this.$toast.info(constant.network_error);
                  });
            } else {
              // 修改身高，实参的单位是米，而形参的单位是厘米，所有需要 * 100
              BmiService.updateHeight(Math.round(Number(this.form.height) * 100))
                  .then(res => {
                    if (res.code === SUCCESS) {
                      this.isOpenDialog = false;
                      this.$toast.info('修改成功');
                      this.loadData();
                    } else {
                      this.$toast.info(res.message);
                    }
                  })
                  .catch(e => {
                    console.log(e);
                    this.$toast.info(constant.network_error);
                  });
            }
          }
        });
      }
    }
  }
</script>

<style scoped>
  #health-index-root {
    width: 100%;
    height: 100%;
    position: absolute;
  }

  #appBar {
    width: 100%;
    flex-shrink: 0;
  }

  #content {
    width: 100%;
    flex: 1 0 0!important;
  }

  #weight {
    font-size: 75px;
    line-height: 1;
  }

  #weight-unit {
    font-size: 20px;
    line-height: 1;
  }

  #height, #bmi, #compare {
    font-size: 22px;
    line-height: 1.5;
  }

  #height-unit, #bmi-text, #compare-unit {
    font-size: 14px;
    line-height: 1.5;
  }

  #height-label, #bmi-label, #compare-label {
    font-size: 16px;
    line-height: 1.5;
  }

  #weight-wrap, #other-wrap {
    width: 100%;
    margin: 16px 0;
  }

  #weight-wrap {
    margin-top: 32px;
  }

  #height-wrap {
    height: auto;
  }

  #height-wrap, #bmi-wrap, #compare-wrap {
    flex: 1 1 0!important;
  }
</style>

<style>
  #health-index-root .mu-flat-button .mu-button-wrapper {
    padding: 0;
  }
</style>